// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod server;

use std::io::Read;
use std::thread;

use base64::Engine;
use base64::engine::general_purpose;
use image::Luma;
use qrcode::QrCode;
use tauri::{Manager, Window};
use tempfile::tempdir;

const MAIN_LABEL: &str = "main";

#[derive(Clone, serde::Serialize)]
struct Payload {
    args: Vec<String>,
    cwd: String,
}

#[tauri::command]
fn gen_qrcode() -> Result<String, String> {
    // Encode some data into bits.
    let code = QrCode::new(b"https://www.rust-lang.org/").unwrap();

    // Render the bits into an image.
    let image = code.render::<Luma<u8>>().build();

    let tmp_dir = tempdir().unwrap();

    let file_path = tmp_dir.path().join("qrcode.png");
    let file_path = file_path.as_path();
    println!("image path: {}", file_path.display());
    image.save(file_path).expect("转图片错误");

    let encoded = file_to_base64(file_path.to_str().unwrap());

    tmp_dir.close().unwrap();

    Ok(encoded)
}

fn file_to_base64(file_path: &str) -> String {
    // 打开文件
    let mut file = std::fs::File::open(file_path).unwrap();
    // 创建一个空的向量以存储文件内容
    let mut contents = Vec::new();
    // 将文件内容读入向量
    file.read_to_end(&mut contents).unwrap();
    // 将向量内容进行Base64编码
    let encoded = general_purpose::STANDARD_NO_PAD.encode(&contents);
    // 返回编码后的结果
    return encoded;
}

fn  main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![
            gen_qrcode
        ])
        //单实例功能实现
        .plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
            println!("{}, {argv:?}, {cwd}", app.package_info().name);
            app.emit_all("single-instance", Payload { args: argv, cwd })
                .unwrap();
        }))
        .setup(|app| {
            let _window: Window = app.get_window(MAIN_LABEL).unwrap();
            // app.listen_global("app-exist",  move |_| app_exist(Some(&window)));

            let handle = app.handle();
            let boxed_handle = Box::new(handle);

            thread::spawn(move || {
                server::init(*boxed_handle).unwrap();
            });

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}


